﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Design;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Windows.Forms.Design.Behavior;
using InkFx.WinControl.Core;

namespace InkFx.WinControl
{
    [ToolboxItem(true), Designer(typeof(SplitControlDesigner))]
    public class BaseSplitControl : System.Windows.Forms.ContainerControl, ISupportInitialize
    {
        public BaseSplitControl()
        {
            SetStyle(Win32API.ControlStylesUAORSD, true);
            base.Margin = Padding.Empty;
            base.Padding = Padding.Empty;


            m_Panel1 = new SplitterPanel(this);
            m_Panel2 = new SplitterPanel(this);

            //m_Panel1.BackColor = Color.Red; //Color.FromArgb(100, Color.Red);  //
            //m_Panel2.BackColor = Color.Blue; //Color.FromArgb(100, Color.Blue);  //

            this.Controls.Add(m_Panel1);
            this.Controls.Add(m_Panel2);



            //base.ResizeRedraw = true;
            this.SplitterWidth = 4;
            ResetRect();
            //base.BackColor = Color.Transparent;
            //m_LastSplitterDistance = base.SplitterDistance;
        }


        #region  字 段 属 性

        protected int m_SplitterWidth = 4;
        protected Orientation m_Orientation = Orientation.Vertical;
        protected SplitterPanel m_Panel1 = null;
        protected SplitterPanel m_Panel2 = null;
        protected int m_Panel1MinSize = 25;
        protected int m_Panel2MinSize = 25;
        protected bool m_Panel1Collapsed = false;
        protected bool m_Panel2Collapsed = false;
        protected int m_Panel1Size = -1;
        protected int m_Panel2Size = -1;
        protected bool m_StopSplitter;
        protected Color m_SplitterColor = Color.FromArgb(50, 0, 0, 0);
        protected FixedPanel m_FixedPanel = FixedPanel.None;
        protected static readonly object m_EventSplitterMoved = new object();
        protected static readonly object m_EventSplitterMoving = new object();


        /// <summary>
        /// 获取或设置拆分器的宽度（以像素为单位）。
        /// </summary>
        /// <returns>
        /// <see cref="T:System.Int32"/>，它表示拆分器的宽度（以像素为单位）。默认值为四个像素。
        /// </returns>
        /// <exception cref="T:System.ArgumentOutOfRangeException">该值小于 1 或与方向不一致。</exception><filterpriority>1</filterpriority><PermissionSet><IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/><IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence"/><IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/></PermissionSet>
        [SRCategory("布局"), Localizable(true), DefaultValue(4)]
        public int SplitterWidth
        {
            get
            {
                return this.m_SplitterWidth;
            }
            set
            {
                if (value == this.SplitterWidth) return;
                this.m_SplitterWidth = value;
                this.m_Panel2Size = -1;
                this.ResetRect();
                this.Invalidate();
            }
        }
        [SRCategory("布局"), DefaultValue(Orientation.Vertical), Localizable(true)]
        public Orientation Orientation
        {
            get
            {
                return this.m_Orientation;
            }
            set
            {
                if (this.m_Orientation == value) return;
                this.m_Orientation = value;
                this.m_Panel2Size = -1;
                this.ResetRect();
                this.Invalidate();
            }
        }

        [SRCategory("布局"), DefaultValue(25), Localizable(true), RefreshProperties(RefreshProperties.All)]
        public int Panel1MinSize
        {
            get
            {
                return this.m_Panel1MinSize;
            }
            set
            {
                if (value < 0) value = 0;
                if (value == this.Panel1MinSize) return;
                this.m_Panel1MinSize = value;
                ResetRect();
                this.Invalidate();
            }
        }
        [SRCategory("布局"), DefaultValue(25), Localizable(true), RefreshProperties(RefreshProperties.All)]
        public int Panel2MinSize
        {
            get
            {
                return this.m_Panel2MinSize;
            }
            set
            {
                if (value < 0) value = 0;
                if (value == this.Panel2MinSize) return;
                this.m_Panel2MinSize = value;
                ResetRect();
                this.Invalidate();
            }
        }
        [SRCategory("布局"), DefaultValue(-1), Localizable(true), SettingsBindable(true)]
        public int SplitterDistance
        {
            get
            {
                //return this.m_Panel1Size;
                if (m_Orientation == Orientation.Horizontal)
                    return (m_RectPanel1.Height >= 1) ? m_RectPanel1.Height : this.m_Panel1Size;
                else
                    return (m_RectPanel1.Width >= 1) ? m_RectPanel1.Width : this.m_Panel1Size;
            }
            set
            {
                if (value < 0) value = 0;
                if (value == this.SplitterDistance) return;
                this.m_Panel1Size = value;
                this.m_Panel2Size = -1;
                ResetRect();
                //this.Panel1.Bounds = m_RectPanel1;
                //this.Panel2.Bounds = m_RectPanel2;
                this.Invalidate();
            }
        }
        [SRCategory("外观"), DefaultValue(typeof(Color), "50, 0, 0, 0"), Localizable(true), SettingsBindable(true)]
        public Color SplitterColor
        {
            get { return this.m_SplitterColor; }
            set
            {
                this.m_SplitterColor = value;
                this.Invalidate();
            }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Localizable(false)]
        public double SplitterDistanceRate
        {
            get
            {
                if (m_Panel1Size <= 0 || m_Panel2Size <= 0) ResetRect();
                return (m_Panel1Size <= 0 || m_Panel2Size <= 0) ? 0 : ((double)m_Panel1Size / (double)(m_Panel1Size + m_Panel2Size));
            }
            set
            {
                value = Math.Min(1, Math.Max(0, value));

                var size = this.ClientSize;
                if (this.Orientation == Orientation.Horizontal)
                    SplitterDistance = (int)Math.Round((size.Height - this.SplitterWidth) * value);
                else
                    SplitterDistance = (int)Math.Round((size.Width - this.SplitterWidth) * value);
            }
        }
        [SRCategory("布局"), DefaultValue(DockStyle.None), Localizable(true), SettingsBindable(true)]
        public new DockStyle Dock
        {
            get { return base.Dock; }
            set
            {
                base.Dock = value;
                ResetRect();
                this.Invalidate();
            } 
        }


        [SRCategory("布局"), DefaultValue(false), Localizable(true), SettingsBindable(true)]
        public bool Panel1Collapsed
        {
            get { return m_Panel1Collapsed; }
            set
            {
                if (value == this.Panel1Collapsed) return;
                m_Panel1Collapsed = value;
                if (m_Panel1Collapsed) m_Panel2Collapsed = false;
                ResetRect();
                this.Invalidate();
            }
        }
        [SRCategory("布局"), DefaultValue(false), Localizable(true), SettingsBindable(true)]
        public bool Panel2Collapsed
        {
            get { return m_Panel2Collapsed; }
            set
            {
                if (value == this.Panel2Collapsed) return;
                m_Panel2Collapsed = value;
                if (m_Panel2Collapsed) m_Panel1Collapsed = false;
                ResetRect();
                this.Invalidate();
            }
        }
        public event SplitterEventHandler SplitterMoved
        {
            add { base.Events.AddHandler(m_EventSplitterMoved, value); }
            remove { base.Events.RemoveHandler(m_EventSplitterMoved, value); }
        }
        public event SplitterCancelEventHandler SplitterMoving
        {
            add { base.Events.AddHandler(m_EventSplitterMoving, value); }
            remove { base.Events.RemoveHandler(m_EventSplitterMoving, value); }
        }



        /// <summary>
        /// 获取或设置在调整容器大小时将大小保持不变的 <see cref="T:System.Windows.Forms.SplitContainer"/> 面板。
        /// </summary>
        /// <returns>
        /// <see cref="T:System.Windows.Forms.FixedPanel"/> 值之一。默认值为 None。
        /// </returns>
        /// <exception cref="T:System.ComponentModel.InvalidEnumArgumentException">分配的值不是 <see cref="T:System.Windows.Forms.FixedPanel"/> 值之一。</exception><filterpriority>2</filterpriority>
        [SRCategory("布局"), DefaultValue(FixedPanel.None)]
        public FixedPanel FixedPanel
        {
            get { return this.m_FixedPanel; }
            set
            {
                if (this.m_FixedPanel == value) return;
                this.m_FixedPanel = value;
                ResetRect();
            }
        }

        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Localizable(false)]
        public override Cursor Cursor
        {
            get { return base.Cursor; }
            set { base.Cursor = value; }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Localizable(false)]
        public bool IsSplitMoving { get; protected set; }




        [Localizable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public SplitterPanel Panel1
        {
            get { return m_Panel1; }
        }
        [Localizable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public SplitterPanel Panel2
        {
            get { return m_Panel2; }
        }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Localizable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new ControlCollection Controls
        {
            get { return base.Controls; }
        }

        #endregion


        #region  函 数 改 写

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            ResetRect();
        }
        protected virtual void OnSplitterMoved(SplitterEventArgs e)
        {
            SplitterEventHandler handler = this.Events[m_EventSplitterMoved] as SplitterEventHandler;
            if (handler != null) handler((object)this, e);
        }
        protected virtual void OnSplitterMoving(SplitterCancelEventArgs e)
        {
            SplitterCancelEventHandler handler = this.Events[m_EventSplitterMoving] as SplitterCancelEventHandler;
            if (handler != null) handler((object)this, e);
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            var point = e.Location;
            var orientation = this.Orientation;

            if (IsSplitMoving)
            {
                SetCursor(orientation == Orientation.Horizontal ? Cursors.HSplit : Cursors.VSplit);

                Rectangle rect = SplitterRectangle;
                Point diff = new Point(m_MoveStartPoint.X - point.X, m_MoveStartPoint.Y - point.Y);
                if (orientation == Orientation.Horizontal) this.RectMovingSplitter = new Rectangle(rect.X, rect.Y - diff.Y, rect.Width, rect.Height);
                else if (orientation == Orientation.Vertical) this.RectMovingSplitter = new Rectangle(rect.X - diff.X, rect.Y, rect.Width, rect.Height);

                OnSplitterMoving(new SplitterCancelEventArgs(e.X, e.Y, this.RectMovingSplitter.X, this.RectMovingSplitter.Y));
                DrawSplitter();
            }
            else if (!this.Panel1Collapsed && !this.Panel2Collapsed)
                SetCursor(this.SplitterRectangle.Contains(point) ? ((orientation == Orientation.Horizontal) ? Cursors.HSplit : Cursors.VSplit) : null);
        }
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            if (!m_StopSplitter && !this.Panel1Collapsed && !this.Panel2Collapsed)
            {
                IsSplitMoving = SplitterRectangle.Contains(e.Location);
                m_MoveStartPoint = e.Location;
                DrawSplitter();
            }
            //this.Invalidate();
        }
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            if (IsSplitMoving)
            {
                var result = EndSplitter();
                if (result) { DoMove(e.Location); }
                IsSplitMoving = false;
                OnSplitterMoved(new SplitterEventArgs(e.X, e.Y, this.RectMovingSplitter.X, this.RectMovingSplitter.Y));
            }
        }
        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            SetCursor(null);
        }
        
        protected override void OnHandleCreated(EventArgs e)
        {
            base.OnHandleCreated(e);
            this.ResetRect();
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);

            var color = this.SplitterColor;
            if (color.A >= 1) GraphicsHelper.FillBack(e.Graphics, this.SplitterRectangle, color, this.Enabled);
            else if (DesignMode) { GraphicsHelper.FillBack(e.Graphics, this.SplitterRectangle, Color.FromArgb(100, Color.Black), this.Enabled); }
        }

        #endregion


        #region  坐 标 区 域


        protected Rectangle m_RectFull = Rectangle.Empty;
        protected Rectangle m_RectMin = Rectangle.Empty;
        protected Rectangle m_RectPanel1 = Rectangle.Empty;
        protected Rectangle m_RectPanel2 = Rectangle.Empty;
        protected Rectangle m_RectSplitter = Rectangle.Empty;

        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Localizable(false)]
        public virtual Rectangle RectPanel1
        {
            get { return m_RectPanel1; }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Localizable(false)]
        public virtual Rectangle RectPanel2
        {
            get { return m_RectPanel2; }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Localizable(false)]
        public virtual Rectangle SplitterRectangle
        {
            get { return m_RectSplitter; }
        }
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Localizable(false)]
        public Rectangle RectMovingSplitter { get; private set; }


        protected bool m_ResetRect = false;
        public void ResetRect()
        {
            var panel1 = this.m_Panel1;
            var panel2 = this.m_Panel2;
            if (panel1 == null || panel2 == null) return;
            if (!this.IsHandleCreated) return;

            var bound = new Rectangle(Point.Empty, this.Size);  //这里不能用 var bound = this.Bounds;
            var fixedPanel = this.FixedPanel;
            var orientation = this.Orientation;
            var splitterWidth = this.SplitterWidth;
            var panel1MinSize = this.Panel1MinSize;
            var panel2MinSize = this.Panel2MinSize;
            var panel1Collapsed = this.Panel1Collapsed;
            var panel2Collapsed = this.Panel2Collapsed;
            var panel1Size = this.m_Panel1Size;
            var panel2Size = this.m_Panel2Size;
            if (bound.Width <= 0 || bound.Height <= 0) return;
            //if (this.Parent == null) return;

            if (m_ResetRect) return;
            m_ResetRect = true;
            panel1.SuspendLayout();
            panel2.SuspendLayout();

            if (orientation == Orientation.Horizontal)
            {
                #region  上 下 分 割

                m_RectMin = new Rectangle(bound.X, bound.Y, bound.Width, splitterWidth + panel1MinSize + panel2MinSize);
                m_RectFull = new Rectangle(bound.X, bound.Y, bound.Width, bound.Height);

                if (panel2Size < 0) panel2Size = m_Panel2Size = bound.Height - splitterWidth - panel1Size;

                int height1 = 0, height2 = 0, heightS = splitterWidth;
                if (fixedPanel == FixedPanel.Panel1) { height1 = panel1Size; }
                else if (fixedPanel == FixedPanel.Panel2){ height1 = bound.Height - splitterWidth - panel2Size; }
                else if (fixedPanel == FixedPanel.None)
                {
                    double rate = (m_Panel1Size <= 0 || m_Panel2Size <= 0) ? -1 : (double)m_Panel1Size / (double)(m_Panel1Size + m_Panel2Size);
                    height1 = (rate < 0 || rate > 1) ? panel1Size : (int)Math.Ceiling((bound.Height - splitterWidth) * rate);
                }
                height2 = bound.Height - height1 - heightS;

                if (height1 < m_Panel1MinSize) { height1 = m_Panel1MinSize; height2 = bound.Height - height1 - heightS; }
                if (height2 < m_Panel2MinSize) { height2 = m_Panel2MinSize; height1 = bound.Height - height2 - heightS; }
                if (height1 < m_Panel1MinSize) { height1 = m_Panel1MinSize; }


                this.m_StopSplitter = (height1 + height2 + heightS) > bound.Height;
                m_RectPanel1 = new Rectangle(0, 0, bound.Width, height1);
                m_RectSplitter = new Rectangle(0, m_RectPanel1.Bottom, bound.Width, splitterWidth);
                m_RectPanel2 = new Rectangle(0, m_RectSplitter.Bottom, bound.Width, height2);
                
                if (panel1Collapsed) { m_RectPanel1 = Rectangle.Empty; m_RectPanel2 = m_RectFull; m_RectSplitter = Rectangle.Empty; }
                if (panel2Collapsed) { m_RectPanel2 = Rectangle.Empty; m_RectPanel1 = m_RectFull; m_RectSplitter = Rectangle.Empty; }

                m_RectSplitRange = (m_RectSplitter.Width <= 0 || m_RectSplitter.Height <= 0) ? Rectangle.Empty : new Rectangle(0, m_Panel1MinSize, bound.Width, bound.Height - m_Panel1MinSize - m_Panel2MinSize);


                m_Panel1.Bounds = m_RectPanel1;
                m_Panel2.Bounds = m_RectPanel2;

                #endregion
            }
            else
            {
                #region  左 右 分 割

                m_RectMin = new Rectangle(bound.X, bound.Y, splitterWidth + panel1MinSize + panel2MinSize, bound.Height);
                m_RectFull = new Rectangle(bound.X, bound.Y, bound.Width, bound.Height);

                if (panel2Size < 0) panel2Size = m_Panel2Size = bound.Width - splitterWidth - panel1Size;


                int width1 = 0, width2 = 0, widthS = splitterWidth;
                if (fixedPanel == FixedPanel.Panel1) { width1 = panel1Size; }
                else if (fixedPanel == FixedPanel.Panel2){ width1 = bound.Width - splitterWidth - panel2Size; }
                else if (fixedPanel == FixedPanel.None)
                {
                    double rate = (m_Panel1Size <= 0 || m_Panel2Size <= 0) ? -1 : (double)m_Panel1Size / (double)(m_Panel1Size + m_Panel2Size);
                    width1 = (rate < 0 || rate > 1) ? panel1Size : (int)Math.Ceiling((bound.Width - splitterWidth) * rate);
                }
                width2 = bound.Width - width1 - widthS;

                if (width1 < m_Panel1MinSize) { width1 = m_Panel1MinSize; width2 = bound.Width - width1 - widthS; }
                if (width2 < m_Panel2MinSize) { width2 = m_Panel2MinSize; width1 = bound.Width - width2 - widthS; }
                if (width1 < m_Panel1MinSize) { width1 = m_Panel1MinSize; }


                this.m_StopSplitter = (width1 + width2 + widthS) > bound.Width;
                m_RectPanel1 = new Rectangle(0, 0, width1, bound.Height);
                m_RectSplitter = new Rectangle(m_RectPanel1.Right, 0, splitterWidth, bound.Height);
                m_RectPanel2 = new Rectangle(m_RectSplitter.Right, 0, width2, bound.Height);
                
                if (panel1Collapsed) { m_RectPanel1 = Rectangle.Empty; m_RectPanel2 = m_RectFull; m_RectSplitter = Rectangle.Empty; }
                if (panel2Collapsed) { m_RectPanel2 = Rectangle.Empty; m_RectPanel1 = m_RectFull; m_RectSplitter = Rectangle.Empty; }

                m_RectSplitRange = (m_RectSplitter.Width <= 0 || m_RectSplitter.Height <= 0) ? Rectangle.Empty : new Rectangle(m_Panel1MinSize, 0, bound.Width - m_Panel1MinSize - m_Panel2MinSize, bound.Height);


                m_Panel1.Bounds = m_RectPanel1;
                m_Panel2.Bounds = m_RectPanel2;

                #endregion
            }

            panel1.ResumeLayout();
            panel2.ResumeLayout();
            m_ResetRect = false;

            //if (this.DesignMode) { MessageBox.Show(this.m_Panel1Size + " | " + this.m_Panel2Size); }
        }

        #endregion


        #region  分 割 拖 拽

        protected SplitterForm m_Splitter;
        protected Point m_MoveStartPoint = Point.Empty;
        protected Rectangle m_RectSplitRange = Rectangle.Empty;

        public Rectangle GetRectSplitter()
        {
            return IsSplitMoving ? RectMovingSplitter : SplitterRectangle;
        }
        public virtual void DrawSplitter()
        {
            if (!IsSplitMoving) return;
            Rectangle rectangle = GetRectSplitter();
            DrawSplitter(m_RectSplitRange, rectangle);

            //Win32API.DrawSplitHelper(this.Handle, new Rectangle(rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height));
            //Rectangle rectangle2 = this.RectangleToClient(this.RectangleToScreen(rectangle));
            //rectangle.Location = new Point(rectangle.X - this.Location.X, rectangle.Y - this.Location.Y);
            //Win32API.DrawSplitHelper(DockPanel.Handle, rectangle2);
            //DockPanel.Refresh();
            //DrawSplitter(rectangle2);
            //Win32API.DrawSplitHelper(this.Handle, rectangle);
        }
        public virtual void DrawSplitter(Rectangle rectRange, Rectangle rectSplit)
        {
            var rectSplit2 = this.RectangleToScreen(rectSplit);
            if (m_Splitter == null) { m_Splitter = SplitterForm.BeginSplitter(this.FindForm(), this.RectangleToScreen(rectRange), rectSplit2); }
            m_Splitter.ShowSplitter(rectSplit2);

            //try
            //{
            //    //m_DrawingSplitter = true;
            //    //m_RectSplitter = rectSplit;
            //    //Win32API.DrawSplitHelper(this.Handle, m_RectSplitter);
            //    //this.Invalidate(RectDockInner, true);
            //    //this.Invalidate(rect, true);
            //    //this.Update();
            //    //this.Refresh();
            //}
            //finally { /*m_DrawingSplitter = false;*/ }
        }
        public virtual bool EndSplitter()
        {
            if (m_Splitter != null)
            {
                var result = m_Splitter.EndSplitter();
                m_Splitter = null;
                return result;
            }
            return false;
        }

        protected virtual void DoMove(Point point)
        {
            if (IsSplitMoving)
            {
                Point diff = new Point(m_MoveStartPoint.X - point.X, m_MoveStartPoint.Y - point.Y);

                var bound = new Rectangle(Point.Empty, this.Size);  //这里不能用 var bound = this.Bounds;
                var orientation = this.Orientation;
                var splitterWidth = this.SplitterWidth;

                this.m_Panel1.SuspendLayout();
                this.m_Panel2.SuspendLayout();

                if (orientation == Orientation.Horizontal)
                {
                    this.m_Panel1.Height = this.m_Panel1.Height - diff.Y;
                    this.m_Panel2.Height = bound.Height - splitterWidth - this.m_Panel1.Height;
                    m_Panel1Size = this.m_Panel1.Height;
                    m_Panel2Size = this.m_Panel2.Height;
                }
                else if (orientation == Orientation.Vertical)
                {
                    this.m_Panel1.Width = this.m_Panel1.Width - diff.X;
                    this.m_Panel2.Width = bound.Width - splitterWidth - this.m_Panel1.Width;
                    m_Panel1Size = this.m_Panel1.Width;
                    m_Panel2Size = this.m_Panel2.Width;
                }

                ResetRect();

                this.m_Panel1.ResumeLayout();
                this.m_Panel2.ResumeLayout();
            }
        }

        #endregion



        #region  其 他 函 数

        protected Cursor m_BakCursor = null;
        protected void SetCursor(System.Windows.Forms.Cursor cursor)
        {
            if (m_BakCursor == null) m_BakCursor = base.Cursor ?? Cursors.Default;
            var baseCursor = base.Cursor;
            if (baseCursor != null && baseCursor != cursor)
                base.Cursor = cursor ?? m_BakCursor;
        }


        public virtual void BeginInit()
        {
        }
        public virtual void EndInit()
        {
            ResetRect();
        }

        #endregion
    }


    [ToolboxItem(false)]
    public class SplitterPanel : SimpPanel  //System.Windows.Forms.Panel //
    {
        public SplitterPanel(InkFx.WinControl.BaseSplitControl owner)
        {
            SetStyle(Win32API.ControlStylesUAORSD, true);
            base.ResizeRedraw = true;
            m_Owner = owner;
        }

        protected InkFx.WinControl.BaseSplitControl m_Owner;
        public InkFx.WinControl.BaseSplitControl Owner
        {
            get { return this.m_Owner; }
        }

        [Browsable(true), DesignerSerializationVisibility(DesignerSerializationVisibility.Visible), EditorBrowsable(EditorBrowsableState.Never)]
        public new Size Size
        {
            get { return base.Size; }
            set { base.Size = value; }
        }

        //protected override CreateParams CreateParams
        //{
        //    get
        //    {
        //        CreateParams cp = base.CreateParams;
        //        cp.ExStyle |= (int)WindowStyles.WS_CLIPCHILDREN;
        //        return cp;
        //    }
        //}
        //protected override void OnPaint(PaintEventArgs e)
        //{
        //    base.OnPaint(e);
        //    e.Graphics.Clear(Color.Violet);
        //}
    }




    public class SplitControlDesigner : ParentControlDesigner
    {
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                IDesignerHost designerHost = (IDesignerHost)this.GetService(typeof(IDesignerHost));
                if (designerHost != null)
                {
                    designerHost.LoadComplete -= new EventHandler(this.OnLoadComplete);
                    designerHost.Activated -= new EventHandler(this.OnDesignerActivate);
                    designerHost.Deactivated -= new EventHandler(this.OnDesignerDeactivate);
                }
                IComponentChangeService componentChangeService = (IComponentChangeService)this.GetService(typeof(IComponentChangeService));
                if (componentChangeService != null)
                {
                    componentChangeService.ComponentAdded -= new ComponentEventHandler(this.OnComponentAdded);
                    componentChangeService.ComponentRemoved -= new ComponentEventHandler(this.OnComponentRemoved);
                }
            }
            base.Dispose(disposing);
        }
        //private void EnsureToolStripWindowAdornerService()
        //{
        //    if (this.toolStripAdornerWindowService == null)
        //    {
        //        this.toolStripAdornerWindowService = (ToolStripAdornerWindowService)this.GetService(typeof(ToolStripAdornerWindowService));
        //    }
        //}
        public override void Initialize(IComponent component)
        {
            //PropertyDescriptor propertyDescriptor = TypeDescriptor.GetProperties(component.GetType())["WindowState"];
            //if (propertyDescriptor != null && propertyDescriptor.PropertyType == typeof(FormWindowState))
            //{
            //    this.WindowState = (FormWindowState)propertyDescriptor.GetValue(component);
            //}
            base.Initialize(component);
            base.AutoResizeHandles = true;
            IDesignerHost designerHost = (IDesignerHost)this.GetService(typeof(IDesignerHost));
            if (designerHost != null)
            {
                designerHost.LoadComplete += new EventHandler(this.OnLoadComplete);
                designerHost.Activated += new EventHandler(this.OnDesignerActivate);
                designerHost.Deactivated += new EventHandler(this.OnDesignerDeactivate);
            }
            InkFx.WinControl.BaseSplitControl host = (InkFx.WinControl.BaseSplitControl)this.Control;
            IComponentChangeService componentChangeService = (IComponentChangeService)this.GetService(typeof(IComponentChangeService));
            if (componentChangeService != null)
            {
                componentChangeService.ComponentAdded += new ComponentEventHandler(this.OnComponentAdded);
                componentChangeService.ComponentRemoved += new ComponentEventHandler(this.OnComponentRemoved);
            }

            this.EnableDesignMode(host.Panel1, "Panel1");
            this.EnableDesignMode(host.Panel2, "Panel2");
        }
        private void OnComponentAdded(object source, ComponentEventArgs ce)
        {
        }
        private void OnComponentRemoved(object source, ComponentEventArgs ce)
        {
        }
        protected override void OnCreateHandle()
        {
        }
        private void OnDesignerActivate(object source, EventArgs evevent)
        {
            System.Windows.Forms.Control control = this.Control;
            if (control != null && control.IsHandleCreated)
            {
                Win32API.SendMessage(control.Handle, 134, 1, 0);
                Win32API.RedrawWindow(control.Handle, IntPtr.Zero, IntPtr.Zero, 1024);
            }
        }
        private void OnDesignerDeactivate(object sender, EventArgs e)
        {
            System.Windows.Forms.Control control = this.Control;
            if (control != null && control.IsHandleCreated)
            {
                Win32API.SendMessage(control.Handle, 134, 0, 0);
                Win32API.RedrawWindow(control.Handle, IntPtr.Zero, IntPtr.Zero, 1024);
            }
        }
        private void OnLoadComplete(object source, EventArgs evevent)
        {
            InkFx.WinControl.BaseSplitControl host = this.Control as InkFx.WinControl.BaseSplitControl;
            if (host != null)
            {
                host.ResetRect();
                BehaviorService behaviorService = (BehaviorService)this.GetService(typeof(BehaviorService));
                if (behaviorService != null) { behaviorService.SyncSelection(); }
            }
        }
        protected override void PreFilterProperties(IDictionary properties)
        {
            base.PreFilterProperties(properties);
            //string[] array = new string[]
            //{
            //    "Opacity",
            //    "Menu",
            //    "IsMdiContainer",
            //    "Size",
            //    "ShowInTaskBar",
            //    "WindowState",
            //    "AutoSize",
            //    "AcceptButton",
            //    "CancelButton"
            //};
            //Attribute[] attributes = new Attribute[0];
            //PropertyDescriptor propertyDescriptor;
            //for (int i = 0; i < array.Length; i++)
            //{
            //    propertyDescriptor = (PropertyDescriptor)properties[array[i]];
            //    if (propertyDescriptor != null)
            //    {
            //        properties[array[i]] = TypeDescriptor.CreateProperty(typeof(InkFx.WinControl.FormDocumentDesigner), propertyDescriptor, attributes);
            //    }
            //}

            //////这段代码可以禁止设置 AutoScaleMode, 且不显示
            ////PropertyDescriptor oldPropertyDescriptor2 = (PropertyDescriptor)properties[(object)"AutoScaleMode"];
            ////if (oldPropertyDescriptor2 != null)
            ////    properties[(object)"AutoScaleMode"] = (object)TypeDescriptor.CreateProperty(typeof(DocumentDesigner), oldPropertyDescriptor2, new Attribute[2]
            ////    {
            ////      (Attribute) DesignerSerializationVisibilityAttribute.Hidden,
            ////      (Attribute) BrowsableAttribute.No
            ////    });

            //////这段代码可以禁止设置 AutoScaleDimensions, 且不显示
            ////PropertyDescriptor oldPropertyDescriptor3 = (PropertyDescriptor)properties[(object)"AutoScaleDimensions"];
            ////if (oldPropertyDescriptor3 != null)
            ////    properties[(object)"AutoScaleDimensions"] = (object)TypeDescriptor.CreateProperty(typeof(DocumentDesigner), oldPropertyDescriptor3, new Attribute[2]
            ////    {
            ////      (Attribute) DesignerSerializationVisibilityAttribute.Hidden,
            ////      (Attribute) BrowsableAttribute.No
            ////    });
        }

        public override ControlDesigner InternalControlDesigner(int internalControlIndex)
        {
            InkFx.WinControl.BaseSplitControl host = (InkFx.WinControl.BaseSplitControl)this.Control;
            SplitterPanel component;
            switch (internalControlIndex)
            {
                case 0:
                    component = host.Panel1;
                    break;
                case 1:
                    component = host.Panel2;
                    break;
                default:
                    return null;
            }

            IDesignerHost designerHost = (IDesignerHost)this.GetService(typeof(IDesignerHost));
            return designerHost == null ? null : designerHost.GetDesigner(component) as ControlDesigner;
        }
        private void WmWindowPosChanging(ref Message m)
        {
            //InkFx.WinControl.BaseSplitControl host = (InkFx.WinControl.BaseSplitControl)this.Control;
            //host.ResetRect();
        }
        protected override void WndProc(ref Message m)
        {
            int msg = m.Msg;
            //if (msg == 70) this.WmWindowPosChanging(ref m);
            base.WndProc(ref m);
        }
    }

}
